package redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import util.JedisPoolUtil;

/**
 * 使用LUA脚本完成秒杀的库存遗留问题
 */
public class SecKillRedisByLua {

    /*
        这里LUA脚本内容就是购票的逻辑
        这里使用了 \" 对引号转义 , 还有换行使用了 \r\n
     */
    static String secKillScript = "local userid=KEYS[1];\r\n" +
            "local ticketno=KEYS[2];\r\n" +
            "local stockKey='sk:'..ticketno..\":ticket\";\r\n" +
            "local usersKey='sk:'..ticketno..\":user\";\r\n" +
            "local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" +
            "if tonumber(userExists)==1 then \r\n" +
            "   return 2;\r\n" +
            "end\r\n" +
            "local num= redis.call(\"get\" ,stockKey);\r\n" +
            "if tonumber(num)<=0 then \r\n" +
            "   return 0;\r\n" +
            "else \r\n" +
            "   redis.call(\"decr\",stockKey);\r\n" +
            "   redis.call(\"sadd\",usersKey,userid);\r\n" +
            "end\r\n" +
            "return 1";

    //使用lua脚本完成秒杀
    public static boolean doSecKill(String userId, String ticketNo) {

        JedisPool jedisPoolInstance = JedisPoolUtil.getJedisPoolInstance();
        Jedis jedis = jedisPoolInstance.getResource();

        //将lua脚本加载到内存，返回校验码
        String sha1 = jedis.scriptLoad(secKillScript);
        //根据返回的sha1校验码，执行缓存在服务器的脚本
        Object result = jedis.evalsha(sha1, 2, userId, ticketNo);
        String resultStr = String.valueOf(result);

        //根据lua脚本执行返回的结果，做相应处理
        if ("0".equals(resultStr)) {
            System.out.println("票已售尽");
            jedis.close();
            return false;
        }

        if("2".equals(resultStr)) {
            System.out.println("不能重复购买..");
            jedis.close();
            return false;
        }

        if("1".equals(resultStr)) {
            System.out.println("抢购成功");
            jedis.close();
            return true;
        } else {
            System.out.println("购票失败..");
            jedis.close();
            return false;
        }

    }
}
